using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Text;
using System.Threading;

namespace FaceCat
{
    /// <summary>
    /// 行的扩展
    /// </summary>
    public class GridRowEx : FCGridRow
    {
        public GridRowEx()
        {
            setHeight(25);
        }

        /// <summary>
        /// 重绘方法
        /// </summary>
        public override void onPaint(FCPaint paint, FCRect clipRect, bool isAlternate)
        {
            FCGrid grid = getGrid();
            ArrayList<FCGridRow> rows = grid.getSelectedRows();
            int rowsSize = rows.size();
            FCRect bounds = getBounds();
            int scrollH = 0, scrollV = 0;
            if (grid.getHScrollBar() != null && grid.getHScrollBar().isVisible())
            {
                scrollH = grid.getHScrollBar().getPos();
            }
            if (grid.getVScrollBar() != null && grid.getVScrollBar().isVisible())
            {
                scrollV = grid.getVScrollBar().getPos();
            }
            bounds.left = 1;
            bounds.top -= scrollV;
            bounds.right = bounds.right - bounds.left;
            bounds.bottom -= scrollV;
            if (rowsSize > 0)
            {
                if (rows.Contains(this))
                {
                    paint.fillRect(MyColor.USERCOLOR219, bounds);
                }
                else
                {
                    if (isAlternate)
                    {
                        if (MyColor.m_style == 0)
                        {
                            paint.fillRect(FCColor.rgb(28, 28, 28), bounds);
                        }
                        else
                        {
                            paint.fillRect(FCColor.rgb(240, 240, 240), bounds);
                        }
                    }
                }
            }
        }
    }

    public class FCGridNoCell : FCGridIntCell
    {
        public override int getInt()
        {
            return m_row.getIndex() + 1;
        }

        public override string getText()
        {
            return FCTran.intToStr(getInt());
        }
    }

    public class FCGridDoubleCellEx : FCGridDoubleCell
    {
        public FCGridDoubleCellEx()
        {
            setDigit(2);
        }

        public bool m_underLine;

        /// <summary>
        /// 重绘方法
        /// </summary>
        /// <param name="paint">绘图对象</param>
        /// <param name="rect">矩形</param>
        /// <param name="clipRect">裁剪矩形</param>
        /// <param name="isAlternate">是否交替行</param>
        public override void onPaint(FCPaint paint, FCRect rect, FCRect clipRect, bool isAlternate)
        {
            int clipW = clipRect.right - clipRect.left;
            int clipH = clipRect.bottom - clipRect.top;
            if (clipW > 0 && clipH > 0)
            {
                if (m_grid != null && m_row != null && m_column != null)
                {
                    //判断选中
                    String text = getPaintText();
                    bool selected = false;
                    if (m_grid.getSelectionMode() == FCGridSelectionMode.SelectCell)
                    {
                        ArrayList<FCGridCell> selectedCells = m_grid.getSelectedCells();
                        int selectedCellSize = selectedCells.size();
                        for (int i = 0; i < selectedCellSize; i++)
                        {
                            if (selectedCells.get(i) == this)
                            {
                                selected = true;
                                break;
                            }
                        }
                    }
                    else if (m_grid.getSelectionMode() == FCGridSelectionMode.SelectFullColumn)
                    {
                        ArrayList<FCGridColumn> selectedColumns = m_grid.getSelectedColumns();
                        int selectedColumnsSize = selectedColumns.size();
                        for (int i = 0; i < selectedColumnsSize; i++)
                        {
                            if (selectedColumns.get(i) == m_column)
                            {
                                selected = true;
                                break;
                            }
                        }
                    }
                    else if (m_grid.getSelectionMode() == FCGridSelectionMode.SelectFullRow)
                    {
                        ArrayList<FCGridRow> selectedRows = m_grid.getSelectedRows();
                        int selectedRowsSize = selectedRows.size();
                        for (int i = 0; i < selectedRowsSize; i++)
                        {
                            if (selectedRows.get(i) == m_row)
                            {
                                selected = true;
                                break;
                            }
                        }
                    }

                    //获取颜色
                    FCFont font = null;
                    long backColor = FCColor.None;
                    long textColor = FCColor.None;
                    bool autoEllipsis = m_grid.autoEllipsis();
                    FCGridRowStyle rowStyle = m_grid.getRowStyle();
                    if (isAlternate)
                    {
                        FCGridRowStyle alternateRowStyle = m_grid.getAlternateRowStyle();
                        if (alternateRowStyle != null)
                        {
                            rowStyle = alternateRowStyle;
                        }
                    }
                    if (rowStyle != null)
                    {
                        if (m_grid.getSelectionMode() != FCGridSelectionMode.SelectFullRow)
                        {
                            if (backColor == FCColor.None)
                            {
                                if (selected)
                                {
                                    backColor = rowStyle.getSelectedBackColor();
                                }
                                else if (m_row == m_grid.getHoveredRow())
                                {
                                    backColor = rowStyle.getHoveredBackColor();
                                }
                                else
                                {
                                    backColor = rowStyle.getBackColor();
                                }
                            }
                        }
                        if (font == null)
                        {
                            font = rowStyle.getFont();
                        }
                        if (textColor == FCColor.None)
                        {
                            if (selected)
                            {
                                textColor = rowStyle.getSelectedTextColor();
                            }
                            else if (m_row == m_grid.getHoveredRow())
                            {
                                textColor = rowStyle.getHoveredTextColor();
                            }
                            else
                            {
                                textColor = rowStyle.getTextColor();
                            }
                        }
                    }

                    FCHorizontalAlign horizontalAlign = m_column.getCellAlign();
                    if (m_style != null)
                    {
                        if (m_style.autoEllipsis())
                        {
                            autoEllipsis = m_style.autoEllipsis();
                        }
                        if (m_style.getBackColor() != FCColor.None)
                        {
                            backColor = m_style.getBackColor();
                        }
                        if (m_style.getFont() != null)
                        {
                            font = m_style.getFont();
                        }
                        if (m_style.getTextColor() != FCColor.None)
                        {
                            textColor = m_style.getTextColor();
                        }
                        if (m_style.getAlign() != FCHorizontalAlign.Inherit)
                        {
                            horizontalAlign = m_style.getAlign();
                        }
                    }
                    FCRect backRect = rect;
                    backRect.bottom -= 1;
                    paint.fillRect(backColor, backRect);
                    FCSize tSize = paint.textSize(text, font, -1);
                    FCPoint tPoint = new FCPoint(rect.left + 1, rect.top + clipH / 2 - tSize.cy / 2);
                    int width = rect.right - rect.left;
                    if (tSize.cx < width)
                    {
                        if (horizontalAlign == FCHorizontalAlign.Center)
                        {
                            tPoint.x = rect.left + (rect.right - rect.left - tSize.cx) / 2;
                        }
                        else if (horizontalAlign == FCHorizontalAlign.Right)
                        {
                            tPoint.x = rect.right - tSize.cx - 2;
                        }
                    }
                    FCRect tRect = new FCRect(tPoint.x, tPoint.y, tPoint.x + tSize.cx, tPoint.y + tSize.cy);
                    if (autoEllipsis && (tRect.right > clipRect.right || tRect.bottom > clipRect.bottom))
                    {
                        if (tRect.right > clipRect.right)
                        {
                            tRect.right = clipRect.right;
                        }
                        if (tRect.bottom > clipRect.bottom)
                        {
                            tRect.bottom = clipRect.bottom;
                        }
                        paint.drawTextAutoEllipsis(text, textColor, font, tRect);
                    }
                    else
                    {
                        paint.drawText(text, textColor, font, tRect, -1);
                    }
                }
            }
        }
    }

    public class FCGridUnitDoubleCell : FCGridDoubleCell
    {
        public FCGridUnitDoubleCell()
        {
            setDigit(2);
        }

        public override string getPaintText()
        {
            double value = getDouble();
            if (value >= 10000000)
            {
                return FCTran.getValueByDigit(value / 10000000, 2) + "亿";
            }
            else if (value >= 10000)
            {
                return FCTran.getValueByDigit(value / 10000, 2) + "万";
            }
            else
            {
                return FCTran.getValueByDigit(value, 2);
            }
        }
    }

    public class FCGridUnitLongCell : FCGridDoubleCell
    {
        public FCGridUnitLongCell()
        {
        }

        public override string getPaintText()
        {
            return FCTran.longToStr((long)getDouble()) + "亿";
        }
    }

    public class FCGridPECell : FCGridDoubleCell
    {
        public FCGridPECell()
        {
            setDigit(2);
        }

        public override string getPaintText()
        {
            double value = getDouble();
            if (value < 0)
            {
                return "亏损";
            }
            else
            {
                return FCTran.getValueByDigit(value, 2);
            }
        }
    }

    /// <summary>
    /// 股票列表
    /// </summary>
    public class SecurityList : FCGrid, FCListenerMessageCallBack, FCInvokeEventCallBack, FCMenuItemTouchEventCallBack
    {
        public SecurityList()
        {
            setFont(new FCFont("Default", 14));
        }

        public int m_requestID = -1;

        /// <summary>
        /// 绑定代码
        /// </summary>
        /// <param name="codes"></param>
        public void bindCodes(ArrayList<Security> codes)
        {
            m_rowsMap.clear();
            clearRows();
            update();
            getSelectedRows().clear();
            beginUpdate();
            m_rows.Capacity = codes.size();
            foreach (Security security in codes)
            {
                if (security.m_name.Length > 0)
                {
                    GridRowEx row = new GridRowEx();
                    addRow(row);
                    row.setHeight(25);
                    String showCode = security.m_code.Substring(0, security.m_code.IndexOf("."));
                    row.setTag(security.m_code);
                    row.m_cells.Capacity = 22;
                    row.addCell("colP0", new FCGridNoCell());
                    row.addCell("colP1", new FCGridStringCell(showCode));
                    row.addCell("colP2", new FCGridStringCell(security.m_name));
                    FCGridDoubleCellEx priceCell = new FCGridDoubleCellEx();
                    priceCell.m_underLine = true;
                    row.addCell("colP3", priceCell);
                    row.addCell("colP4", new FCGridPercentCell());
                    row.addCell("colP5", new FCGridDoubleCellEx());
                    row.addCell("colP9", new FCGridUnitDoubleCell());
                    row.addCell("colP10", new FCGridUnitDoubleCell());
                    row.addCell("colP11", new FCGridDoubleCellEx());
                    row.addCell("colP12", new FCGridPECell());
                    row.addCell("colP13", new FCGridPercentCell());
                    row.addCell("colP14", new FCGridPercentCell());
                    row.addCell("colP15", new FCGridUnitLongCell());
                    row.addCell("colP16", new FCGridUnitLongCell());
                    row.addCell("colP17", new FCGridStringCell());
                    row.addCell("colP18", new FCGridDoubleCellEx());
                    row.addCell("colP19", new FCGridDoubleCellEx());
                    row.addCell("colP20", new FCGridDoubleCellEx());
                    row.addCell("colP21", new FCGridPercentCell());
                    row.addCell("colP22", new FCGridPercentCell());
                    row.addCell("colP23", new FCGridPercentCell());
                    row.addCell("colP24", new FCGridDoubleCell());
                    m_rowsMap[security.m_code] = row;
                    for (int i = 0; i < row.m_cells.size(); i++)
                    {
                        FCGridCell cell = row.m_cells.get(i);
                        FCGridCellStyle cellStyle = new FCGridCellStyle();
                        cell.setStyle(cellStyle);
                        if (i == 0 || i == 2)
                        {
                            cellStyle.m_textColor = MyColor.USERCOLOR217;
                        }
                        else
                        {
                            cellStyle.m_textColor = MyColor.USERCOLOR218;
                        }
                    }
                }
            }
            endUpdate();
        }

        /// <summary>
        /// 行的缓存
        /// </summary>
        private HashMap<String, FCGridRow> m_rowsMap = new HashMap<String, FCGridRow>();

        /// <summary>
        /// 跨线程调用
        /// </summary>
        /// <param name="eventName"></param>
        /// <param name="sender"></param>
        /// <param name="args"></param>
        /// <param name="invoke"></param>
        public void callInvokeEvent(string eventName, object sender, object args, object invoke)
        {
            if (args != null)
            {
                FCMessage message = args as FCMessage;
                if (message != null)
                {
                    if (message.m_serviceID == PriceDataServiceClient.SERVICEID)
                    {
                        if (message.m_functionID == PriceDataServiceClient.FUNCTION_NEWDATA)
                        {
                            HashMap<String, int> columnsMap = new HashMap<String, int>();
                            for (int i = 0; i < m_columns.size(); i++)
                            {
                                FCGridColumn gridColumn = m_columns.get(i);
                                columnsMap.put(gridColumn.getName(), gridColumn.getIndex());
                            }
                            ArrayList<int> columnIndex = new ArrayList<int>();
                            columnIndex.add(columnsMap.get("colP3"));
                            columnIndex.add(columnsMap.get("colP4"));
                            columnIndex.add(columnsMap.get("colP5"));
                            columnIndex.add(columnsMap.get("colP9"));
                            columnIndex.add(columnsMap.get("colP10"));
                            columnIndex.add(columnsMap.get("colP11"));
                            columnIndex.add(columnsMap.get("colP12"));
                            columnIndex.add(columnsMap.get("colP13"));
                            columnIndex.add(columnsMap.get("colP14"));
                            columnIndex.add(columnsMap.get("colP15"));
                            columnIndex.add(columnsMap.get("colP16"));
                            columnIndex.add(columnsMap.get("colP17"));
                            columnIndex.add(columnsMap.get("colP18"));
                            columnIndex.add(columnsMap.get("colP19"));
                            columnIndex.add(columnsMap.get("colP20"));
                            columnIndex.add(columnsMap.get("colP21"));
                            columnIndex.add(columnsMap.get("colP22"));
                            columnIndex.add(columnsMap.get("colP23"));
                            columnIndex.add(columnsMap.get("colP24"));
                            ArrayList<PriceData> priceDatas = PriceDataServiceClient.getPriceDatas(message.m_body, message.m_bodyLength);
                            for (int i = 0; i < priceDatas.size(); i++)
                            {
                                PriceData priceData = priceDatas.get(i);
                                String code = priceData.m_code;
                                if (m_rowsMap.containsKey(code))
                                {
                                    FCGridRow row = m_rowsMap.get(code);
                                    double lastClose = priceData.m_lastClose;
                                    double diff = 0, diffRange = 0;
                                    double close = priceData.m_close;
                                    if (close > 0)
                                    {
                                        diff = close - priceData.m_lastClose;
                                    }
                                    if (close > 0 && priceData.m_lastClose != 0)
                                    {
                                        diffRange = diff / priceData.m_lastClose;
                                    }
                                    FCGridCell cell3 = row.getCell(columnIndex.get(0));
                                    cell3.setDouble(close);
                                    if (close > 0 && close == priceData.m_upperLimit)
                                    {
                                        cell3.m_style.m_backColor = FCColor.rgb(255, 82, 82);
                                        cell3.m_style.m_textColor = FCColor.Back;
                                    }
                                    else if (close > 0 && close == priceData.m_lowerLimit)
                                    {
                                        cell3.m_style.m_backColor = FCColor.rgb(82, 255, 82);
                                        cell3.m_style.m_textColor = FCColor.Back;
                                    }
                                    else
                                    {
                                        cell3.m_style.m_backColor = FCColor.None;
                                        cell3.m_style.m_textColor = FCDraw.getPriceColor(close, lastClose);
                                    }

                                    FCGridCell cell4 = row.getCell(columnIndex.get(1));
                                    cell4.setDouble(diffRange);
                                    cell4.m_style.m_textColor = FCDraw.getPriceColor(close, lastClose);

                                    FCGridCell cell5 = row.getCell(columnIndex.get(2));
                                    cell5.setDouble(diff);
                                    cell5.m_style.m_textColor = FCDraw.getPriceColor(close, lastClose);

                                    FCGridCell cell9 = row.getCell(columnIndex.get(3));
                                    cell9.setDouble(priceData.m_volume / 100);

                                    FCGridCell cell10 = row.getCell(columnIndex.get(4));
                                    cell10.setDouble(priceData.m_amount);

                                    FCGridCell cell11 = row.getCell(columnIndex.get(5));
                                    cell11.setDouble(priceData.m_ratio);

                                    FCGridCell cell12 = row.getCell(columnIndex.get(6));
                                    cell12.setDouble(priceData.m_pe);

                                    double range = 0;
                                    if (lastClose != 0)
                                    {
                                        range = (priceData.m_high - lastClose) / lastClose - (priceData.m_low - lastClose) / lastClose;
                                    }
                                    FCGridCell cell13 = row.getCell(columnIndex.get(7));
                                    cell13.setDouble(range);
                                    FCGridCell cell14 = row.getCell(columnIndex.get(8));
                                    cell14.setDouble(priceData.m_turnoverRate / 100);
                                    FCGridCell cell15 = row.getCell(columnIndex.get(9));
                                    cell15.setDouble(priceData.m_marketValue);
                                    FCGridCell cell16 = row.getCell(columnIndex.get(10));
                                    cell16.setDouble(priceData.m_flow);
                                    FCGridCell cell17 = row.getCell(columnIndex.get(11));
                                    if (DataCenter.m_securityService.m_securitiesMap.ContainsKey(code))
                                    {
                                        cell17.setString(DataCenter.m_securityService.m_securitiesMap[code].m_block);
                                    }
                                    FCGridCell cell18 = row.getCell(columnIndex.get(12));
                                    cell18.setDouble(priceData.m_upperLimit);
                                    cell18.m_style.m_textColor = FCDraw.getPriceColor(priceData.m_upperLimit, lastClose);
                                    FCGridCell cell19 = row.getCell(columnIndex.get(13));
                                    cell19.setDouble(priceData.m_lowerLimit);
                                    cell19.m_style.m_textColor = FCDraw.getPriceColor(priceData.m_lowerLimit, lastClose);

                                }
                            }
                            invalidate();
                        }
                    }
                }
            }
            else
            {
                ArrayList<Security> securities = new ArrayList<Security>();
                for (int i = 0; i < m_rows.size(); i++)
                {
                    FCGridRow row = m_rows.get(i);
                    String sCode = row.getTag().ToString();
                    if (DataCenter.m_securityService.m_securitiesMap.ContainsKey(sCode))
                    {
                        securities.add(DataCenter.m_securityService.m_securitiesMap[sCode]);
                    }
                }
                clearRows();
                update();
                invalidate();
                searchCodes(securities);
            }
        }

        /// <summary>
        /// 回调方法
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="message"></param>
        /// <param name="invoke"></param>
        public void callListenerMessageEvent(Object sender, FCMessage message, Object invoke)
        {
            this.invoke(message);
        }

        /// <summary>
        /// 销毁方法
        /// </summary>
        public override void delete()
        {
            if (!isDeleted())
            {
                DataCenter.m_priceDataServiceClient.removeListener(m_requestID);
                DataCenter.m_priceDataServiceClient.unSubCodes(m_requestID);
            }
            base.delete();
        }

        public FCMenu m_menu;

        public bool m_clickLeftOrRight;

        public override void onTouchDown(FCTouchInfo touchInfo)
        {
            callTouchEvents("ontouchdown", touchInfo);
            if (!allowPreviewsEvent())
            {
                onDragScrollStart();
            }
            m_clickLeftOrRight = touchInfo.m_firstTouch;
            touchEvent(touchInfo, 1);
        }

        public override void onTouchUp(FCTouchInfo touchInfo)
        {
            base.onTouchUp(touchInfo);
            if (touchInfo.m_secondTouch)
            {
                if (m_menu == null)
                {
                    m_menu = new FCMenu();
                    m_menu.setPopup(true);
                    m_menu.setWidth(100);
                    m_menu.setMinimumSize(new FCSize(100, 25));
                    m_menu.addEvent(this, "onmenuitemclick", this);
                    m_native.addView(m_menu);
                    ArrayList<String> titles = new ArrayList<String>();
                    titles.add("进入全屏");
                    for (int i = 0; i < titles.size(); i++)
                    {
                        FCMenuItem menuItem1 = new FCMenuItem(titles[i]);
                        m_menu.addItem(menuItem1);
                    }
                }
                if (m_oldParent != null)
                {
                    m_menu.m_items.get(0).setText("退出全屏");
                }
                else
                {
                    m_menu.m_items.get(0).setText("进入全屏");
                }
                m_menu.setLocation(m_native.getTouchPoint());
                m_menu.show();
                getNative().invalidate();
            }
        }

        public bool m_firstAdd = true;

        /// <summary>
        /// 添加视图方法
        /// </summary>
        public override void onAdd()
        {
            base.onAdd();
            if (m_firstAdd)
            {
                m_firstAdd = false;
                addEvent(this, "oninvoke", this);
            }
        }

        /// <summary>
        /// 查询数据
        /// </summary>
        /// <param name="securities"></param>
        public void searchCodes(ArrayList<Security> securities)
        {
            if (m_requestID != -1)
            {
                DataCenter.m_priceDataServiceClient.removeListener(m_requestID);
                DataCenter.m_priceDataServiceClient.unSubCodes(m_requestID);
            }
            bindCodes(securities);
            m_requestID = FCClientService.getRequestID();
            DataCenter.m_priceDataServiceClient.addListener(m_requestID, this, this);
            StringBuilder sb = new StringBuilder();
            foreach (Security security in securities)
            {
                sb.Append(security.m_code + ",");
            }
            String codes = sb.ToString();
            if (codes.EndsWith(","))
            {
                codes = codes.Substring(0, codes.Length - 1);
            }
            DataCenter.m_priceDataServiceClient.subCodes(m_requestID, codes);
        }

        /// <summary>
        /// 第一次搜索代码
        /// </summary>
        public void firstSearchCode()
        {
            ArrayList<Security> securities = new ArrayList<Security>();
            foreach (Security security in DataCenter.m_securityService.m_securities)
            {
                if (security.m_type != 0)
                {
                    securities.add(security);
                }
            }
            searchCodes(securities);
        }

        public override void onKeyDown(char key)
        {
            base.onKeyDown(key);
            m_isKeyDown = true;
        }

        public override void onKeyUp(char key)
        {
            base.onKeyUp(key);
            m_isKeyDown = false;
            if (m_searchCode.Length > 0)
            {
                MainFrame.m_mainFrame.searchCode(m_searchCode);
            }
            m_searchCode = "";
        }

        public bool m_isKeyDown = false;

        public String m_searchCode = "";

        public override void onSelectedRowsChanged()
        {
            base.onSelectedRowsChanged();
            try
            {
                if (m_clickLeftOrRight)
                {
                    if (getSelectedRows().get(0).m_cells.size() > 0)
                    {
                        String code = getSelectedRows().get(0).getTag().ToString();
                        if (m_isKeyDown)
                        {
                            m_searchCode = code;
                        }
                        else
                        {
                            MainFrame.m_mainFrame.searchCode(code);
                        }
                    }
                }
            }
            catch (Exception ex)
            {

            }
        }

        public FCSplitLayoutDiv m_oldParent;

        public int m_isFirstOrSecond;

        public void fullScreen()
        {
            FCView linkControl = m_native.findView("divInner");
            if (this.getParent() != linkControl)
            {
                m_oldParent = this.getParent() as FCSplitLayoutDiv;
                setDock(FCDockStyle.Fill);
                m_oldParent.removeView(this);
                if (m_oldParent.getFirstView() == this)
                {
                    m_isFirstOrSecond = 0;
                    m_oldParent.setFirstView(null);
                }
                else if (m_oldParent.getSecondView() == this)
                {
                    m_isFirstOrSecond = 1;
                    m_oldParent.setSecondView(null);
                }
                m_native.findView("tabFunc").setVisible(false);
                linkControl.addView(this);
            }
            else
            {
                m_native.findView("tabFunc").setVisible(true);
                linkControl.removeView(this);
                m_oldParent.addView(this);
                if (m_isFirstOrSecond == 0)
                {
                    m_oldParent.setFirstView(this);
                }
                else
                {
                    m_oldParent.setSecondView(this);
                }
                m_oldParent = null;
            }
            getNative().update();
            getNative().invalidate();
        }

        /// <summary>
        /// 右键菜单点击事件
        /// </summary>
        /// <param name="eventName"></param>
        /// <param name="sender"></param>
        /// <param name="item"></param>
        /// <param name="touchInfo"></param>
        /// <param name="invoke"></param>
        public void callMenuItemTouchEvent(string eventName, object sender, FCMenuItem item, FCTouchInfo touchInfo, object invoke)
        {
            if (item.getText() == "进入全屏" || item.getText() == "退出全屏")
            {
                fullScreen();
            }
        }
    }
}
